#lang racket/base
(provide
 #%sp:datum
 #%sp:primop
 #%sp:app
 #%sp:λ
 #%sp:let
 #%sp:def
 #%sp:splice
 (for-syntax
  valid-datum?
  core-literals
  core-literal-ids
  core-literal-ids/set))

(require
 (for-syntax
  racket/base
  syntax/parse
  syntax/id-set))

(define-for-syntax (valid-datum? x)
  (or (exact-integer? x)
      (flonum? x)
      (string? x)
      (char? x)
      (symbol? x)
      (eq? x #t)
      (eq? x #f)))

(define-syntax-rule (define-special x)
  (define-syntax (x stx)
    (raise-syntax-error
     #f
     (format "invalid use of ~a in Racket context" 'x)
     stx)))

(define-syntax define-special*
  (syntax-parser
    [(_ lit-set:id lit-ids:id [x:id ...])
     #'(begin
         (define-special x) ...
         (begin-for-syntax
           (define lit-ids (list #'x ...))
           (define-literal-set lit-set [x ...])))]))

(define-special* core-literals core-literal-ids
  [#%sp:datum
   #%sp:primop
   #%sp:app
   #%sp:λ
   #%sp:let
   #%sp:def
   #%sp:splice])

(define-for-syntax core-literal-ids/set
  (immutable-free-id-set
   core-literal-ids))
